class Quantity:
    # 描述符基于协议实现，无需创建子类

    def __init__(self, storage_name):
        self.storage_name = storage_name

    # self 是描述符实例（即 LineItem.weight 或 LineItem.price）
    # instance是托管实例（LineItem 实例），
    def __set__(self, instance, value):
        if value > 0:
            instance.__dict__[self.storage_name] = value
        else:
            raise ValueError('value must be >0')
    # 读值方法不需要特殊的逻辑 不需要定义 __get__ 方法


class LineItem:
    weight = Quantity('weight')
    price = Quantity('price')

    def __init__(self, description, weight, price):
        self.description = description
        self.weight = weight
        self.price = price

    def subtotal(self):
        return self.weight * self.price


if __name__ == '__main__':
    truffle = LineItem('white truffle', 100, 10)
    print(truffle.weight)
